package com.woniu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netflix.hystrix.exception.HystrixTimeoutException;
import com.woniu.client.AccountClient;
import com.woniu.client.VenueClient;
import com.woniu.client.accountdto.CoachResumeDto;
import com.woniu.commons.exception.VenueRuntimeException;
import com.woniu.commons.exception.YogaException;
import com.woniu.commons.model.RedisKey;
import com.woniu.commons.model.StateData;
import com.woniu.dao.YCoachEnterMapper;
import com.woniu.dao.YCoachEnterVenueMapper;
import com.woniu.dao.YVenueBaseMapper;
import com.woniu.dao.YVenueCoachMapper;
import com.woniu.model.dto.CoachEnterDto;
import com.woniu.model.dto.VenueLoadCoachDto;
import com.woniu.model.form.AddCoachEnterVanueForm;
import com.woniu.model.form.CoachEnterPlateForm;
import com.woniu.model.form.PageCoachEnterForm;
import com.woniu.model.form.rejectCoachEnterPlateForm;
import com.woniu.model.model.*;
import com.woniu.model.param.PageCoachEnterParam;
import com.woniu.service.YCoachEnterService;
import feign.Param;
import io.seata.spring.annotation.GlobalTransactional;
import org.bouncycastle.math.ec.ScaleXNegateYPointMap;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author EdisonLiu
 * @since 2024年05月23日
 */
@Service
public class YCoachEnterServiceImpl extends ServiceImpl<YCoachEnterMapper, YCoachEnter> implements YCoachEnterService {

    @Resource
    private YCoachEnterMapper coachEnterMapper;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private AccountClient accountClient;
    @Resource
    private YVenueCoachMapper venueCoachMapper;
    @Resource
    private YCoachEnterVenueMapper coachEnterVenueMapper;
    @Resource
    private YVenueBaseMapper venueBaseMapper;

    @Override
    public Integer coachEnterPlate(CoachEnterPlateForm form) throws YogaException{

        RLock fairLock = redissonClient.getFairLock(RedisKey.coachEnterUpdateLock(form.getCoachId()));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                List<YCoachEnter> enters = coachEnterMapper.selectList(new QueryWrapper<YCoachEnter>().eq("coach_id", form.getCoachId()).eq("enter_venue_id", 0).eq("enter_state", StateData.ENTER_STATE_APPLY));
                if (enters.size()!=0){
                    throw new YogaException(3003,"已申请，请等待,请勿重复提交");
                }

                System.out.println(accountClient.loadCoachResumeByCoachId(form.getCoachId()).getData()+"业务层的查询");
                if (accountClient.loadCoachResumeByCoachId(form.getCoachId()).getData().getCardImage()==null) {
                    throw new YogaException(3004,"还没有填写简历，请先完善简历后提交");
                }
                System.out.println(accountClient.byId(form.getCoachId()).getData()+"业务层查回来教练的对象");
                if (accountClient.byId(form.getCoachId()).getData().getCoachRemark()==null) {
                    throw new YogaException(3005,"还没有完善个人信息，请先完善个人信息后提交");
                }



                YCoachEnter c = baseMapper.selectOne(new QueryWrapper<YCoachEnter>().eq("coach_id", form.getCoachId()).eq("enter_state", StateData.ENTER_STATE_SUCCES).eq("enter_venue_id", 0));
                if (c!=null){
                    throw new VenueRuntimeException(3120,"已成功入驻平台");
                }

                YCoachEnter coachEnter = new YCoachEnter();
                coachEnter.setCoachId(form.getCoachId());
                coachEnter.setEnterVenueId(0);
                coachEnter.setEnterState(StateData.ENTER_STATE_APPLY);
                coachEnter.setCreateTime(LocalDateTime.now());

                i = coachEnterMapper.insert(coachEnter);
            } else {
                throw new YogaException(500,"服务器繁忙");
            }

        }  catch (InterruptedException e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;




    }

    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public Integer passCoachEnterPlate(Integer coachId) {
        RLock fairLock = redissonClient.getFairLock(RedisKey.coachEnterUpdateLock(coachId));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                YCoachEnter coachEnter = coachEnterMapper.selectOne(new QueryWrapper<YCoachEnter>().eq("coach_id", coachId).eq("enter_venue_id", 0).eq("enter_state", StateData.ENTER_STATE_APPLY));

                if (coachEnter==null){
                    throw new VenueRuntimeException(3004,"不存在该申请");
                }

                coachEnter.setDealTime(LocalDateTime.now());
                coachEnter.setEnterState(StateData.ENTER_STATE_SUCCES);

                i = coachEnterMapper.updateById(coachEnter);

                YCoach coach = new YCoach();
                coach.setCoachId(coachId);
                coach.setCoachState(1);

                accountClient.updateCoach(coach);
            } else {
                throw new Exception("服务器繁忙");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;
    }

    @Override
    public Integer rejectCoachEnterPlate(rejectCoachEnterPlateForm form) {
        RLock fairLock = redissonClient.getFairLock(RedisKey.coachEnterUpdateLock(form.getCoachId()));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                YCoachEnter coachEnter = coachEnterMapper.selectOne(new QueryWrapper<YCoachEnter>().eq("coach_id", form.getCoachId()).eq("enter_venue_id", 0).eq("enter_state", StateData.ENTER_STATE_APPLY));

                if (coachEnter==null){
                    throw new VenueRuntimeException(3004,"不存在该申请");
                }

                coachEnter.setRemark(form.getRemark());
                coachEnter.setDealTime(LocalDateTime.now());
                coachEnter.setEnterState(StateData.ENTER_STATE_REJECT);

                i = coachEnterMapper.updateById(coachEnter);
            } else {
                throw new Exception("服务器繁忙");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;
    }

    @Override
    public Integer addCoachEnterVenue(CoachEnterPlateForm form) {
        RLock fairLock = redissonClient.getFairLock(RedisKey.coachEnterUpdateLock(form.getCoachId()));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                List<YCoachEnter> enters = coachEnterMapper.selectList(new QueryWrapper<YCoachEnter>().eq("coach_id", form.getCoachId()).eq("enter_state", StateData.ENTER_STATE_APPLY));
                if (enters.size()!=0){
                    throw new VenueRuntimeException(3003,"已申请");
                }
                YCoachEnter coachEnter = new YCoachEnter();
                coachEnter.setCoachId(form.getCoachId());
                coachEnter.setEnterVenueId(form.getEnterVenueId());
                coachEnter.setEnterState(StateData.ENTER_STATE_APPLY);
                coachEnter.setCreateTime(LocalDateTime.now());

                i = coachEnterMapper.insert(coachEnter);
            } else {
                throw new YogaException(500,"服务器繁忙");
            }

        } catch (YogaException e) {
            throw new RuntimeException(e.getMessage());
        } catch (InterruptedException e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;
    }

    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public Integer passCoachEnterVenue(Integer coachId) {
        RLock fairLock = redissonClient.getFairLock(RedisKey.coachEnterUpdateLock(coachId));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                YCoachEnter coachEnter = coachEnterMapper.selectOne(new QueryWrapper<YCoachEnter>().eq("coach_id", coachId).eq("enter_state", StateData.ENTER_STATE_APPLY));

                if (coachEnter==null){
                    throw new VenueRuntimeException(3004,"不存在该申请");
                }


                coachEnter.setEnterState(StateData.ENTER_STATE_SUCCES);
                coachEnter.setDealTime(LocalDateTime.now());

                i = coachEnterMapper.updateById(coachEnter);



                YCoach coachInfo = accountClient.byId(coachId).getData();

                CoachResumeDto coachResume = accountClient.loadCoachResumeByCoachId(coachId).getData();


                List<YVenueCoach> yVenueCoaches = venueCoachMapper.selectList(new QueryWrapper<YVenueCoach>().eq("coach_id", coachId).eq("coach_state", StateData.COACH_STATE_OK).eq("venue_id",coachEnter.getEnterVenueId()));
                if (yVenueCoaches.size()!=0){
                    throw new VenueRuntimeException(3006,"该教练已在本场馆任职");
                }

                YVenueCoach venueCoach = new YVenueCoach();
                venueCoach.setCoachId(coachId);
                venueCoach.setVenueId(coachEnter.getEnterVenueId());
                venueCoach.setCoachTypeId((coachInfo.getCoachPersonal()+1));
                venueCoach.setCoachPhone(coachInfo.getCoachPhone());
                venueCoach.setCoachState(1);
                venueCoach.setCardImage(coachResume.getCardImage());
                venueCoach.setJoinDate(LocalDateTime.now());

                venueCoachMapper.insert(venueCoach);

//                venueClient.addCoachEnterVanue(new AddCoachEnterVanueForm(coachId,coachEnter.getEnterVenueId()));

                YCoachEnterVenue coachEnterVenue = new YCoachEnterVenue();
                coachEnterVenue.setCoachId(coachId);
                coachEnterVenue.setVenueId(coachEnter.getEnterVenueId());
                coachEnterVenueMapper.insert(coachEnterVenue);

            } else {
                throw new Exception("服务器繁忙");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;
    }


    @Override
    public Page<CoachEnterDto> pageCoachEnterByVenueId(PageCoachEnterParam param) {
        param.setPageNum(param.getPageNum() == null ? 1 : param.getPageNum());
        param.setPageSize(param.getPageSize() == null ? 5 : param.getPageSize());

        QueryWrapper<YCoachEnter> wrapper = new QueryWrapper<>();
        wrapper.eq("enter_venue_id",param.getVenueId());
        if (param.getEnterState()!=null){
            wrapper.eq("enter_state",param.getEnterState());
        }

        Page<YCoachEnter> page = new Page<>(param.getPageNum(), param.getPageSize());

        Page<YCoachEnter> yCoachEnterPage = coachEnterMapper.selectPage(page, wrapper);


        Page<CoachEnterDto> dtoPage = new Page<CoachEnterDto>();
        dtoPage.setCurrent(yCoachEnterPage.getCurrent());
        dtoPage.setOptimizeCountSql(yCoachEnterPage.optimizeCountSql());
        dtoPage.setPages(yCoachEnterPage.getPages());
        dtoPage.setSearchCount(yCoachEnterPage.searchCount());
        dtoPage.setSize(yCoachEnterPage.getSize());
        dtoPage.setTotal(yCoachEnterPage.getTotal());


        ArrayList<CoachEnterDto> dto = new ArrayList<>();

        for (YCoachEnter coachEnter:yCoachEnterPage.getRecords()){

            CoachEnterDto coachDto = BeanUtil.toBean(coachEnter, CoachEnterDto.class);

            //通过教练ID查出教练名字赋值给dto
            String coachName = accountClient.byId(coachEnter.getCoachId()).getData().getCoachName();
            if (coachName == null){
                throw new YogaException(500,"请先招募教练");
            }
            coachDto.setCoachName(coachName);

            YVenueBase yVenueBase = venueBaseMapper.selectById(coachEnter.getCoachId());
            if (yVenueBase==null){
                throw new YogaException(500,"场馆不存在");
            }
            coachDto.setVenueName(yVenueBase.getVenueName());


            dto.add(coachDto);
        }
        dtoPage.setRecords(dto);
        return dtoPage;
    }


    /**
     * 管理员浏览教练的入驻平台申请 分页展示
     * @param form 分页信息及审批状态
     * @return
     */
    @Override
    public Page<CoachEnterDto> pageCoachEnterPlateByVenueId(PageCoachEnterForm form) {
        form.setPageNum(form.getPageNum() == null ? 1 : form.getPageNum());
        form.setPageSize(form.getPageSize() == null ? 5 : form.getPageSize());

        Page<YCoachEnter> page = new Page<>(form.getPageNum(), form.getPageSize());
        QueryWrapper<YCoachEnter> wrapper = new QueryWrapper<>();
        wrapper.eq("enter_venue_id",0);
        if(form.getEnterState()!=null){
            wrapper.eq("enter_state", form.getEnterState());
        }
        Page<YCoachEnter> enterPage = coachEnterMapper.selectPage(page, wrapper);

        Page<CoachEnterDto> dtoPage = new Page<CoachEnterDto>();
        dtoPage.setCurrent(enterPage.getCurrent());
        dtoPage.setOptimizeCountSql(enterPage.optimizeCountSql());
        dtoPage.setPages(enterPage.getPages());
        dtoPage.setSearchCount(enterPage.searchCount());
        dtoPage.setSize(enterPage.getSize());
        dtoPage.setTotal(enterPage.getTotal());

        ArrayList<CoachEnterDto> dto = new ArrayList<>();

        for (YCoachEnter coachEnter:enterPage.getRecords()){
            CoachEnterDto enterDto = BeanUtil.toBean(coachEnter, CoachEnterDto.class);

            //通过教练ID查出教练名字赋值给dto
            String coachName = accountClient.byId(coachEnter.getCoachId()).getData().getCoachName();
            if (coachName == null){
                throw new YogaException(500,"请先招募教练");
            }
            enterDto.setCoachName(coachName);

            dto.add(enterDto);
        }
        dtoPage.setRecords(dto);
        return dtoPage;
    }






}
